<template>
  <div class="point-cloud-viewer">
    <!-- 渲染容器 -->
    <div ref="renderContainer" class="render-container"></div>

    <!-- 加载状态 -->
    <div v-if="loading" class="loading-mask">
      <div class="loading-text">加载点云数据中...</div>
    </div>

    <!-- 错误提示 -->
    <div v-if="error" class="error-message">
      <span>⚠️ {{ errorMessage }}</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'
import api from '@/auth/myaxios' // 替换为你的 axios 实例

// 接收文物ID（用于请求点云数据）
const props = defineProps({
  relicId: {
    type: Number,
    required: true
  }
})

// 状态管理
const renderContainer = ref<HTMLDivElement | null>(null)
const loading = ref(true)
const error = ref(false)
const errorMessage = ref('')
const pointSize = ref(1.5)

// Three.js核心对象
let scene: THREE.Scene
let camera: THREE.PerspectiveCamera
let renderer: THREE.WebGLRenderer
let controls: OrbitControls
let pointCloud: THREE.Points | null = null

// 初始化场景
const initScene = () => {
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x1a1a1a)

  // 相机
  camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000)
  camera.position.z = 50

  // 渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(600, 400)
  renderer.setPixelRatio(window.devicePixelRatio)

  const container = renderContainer.value
  if (container) {
    container.appendChild(renderer.domElement)
  }

  // 控制器
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.1
  controls.enableZoom = true
  controls.enablePan = true

  // 光源
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.6)
  scene.add(ambientLight)
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
  directionalLight.position.set(30, 50, 20)
  scene.add(directionalLight)

  animate()
}

// 加载点云数据
const loadPointCloud = async () => {
  loading.value = true
  error.value = false
  errorMessage.value = ''

  try {
    const response = await api.get(`/api/relics/${props.relicId}/point-cloud/`, {
      responseType: 'arraybuffer'
    })

    const loader = new PLYLoader()
    const geometry = loader.parse(response.data)

    console.log('PLY Geometry:', geometry)
    console.log('Point count:', geometry.attributes.position.count)

    // 删除 color 属性防止着色器错误（如果无颜色数据）
    if (!geometry.attributes.color) {
      geometry.deleteAttribute('color')
    }

    const material = new THREE.PointsMaterial({
      size: pointSize.value,
      color: 0xffffff,
      transparent: true,
      opacity: 0.8,
      sizeAttenuation: false
    })

    if (pointCloud) {
      scene.remove(pointCloud)
    }

    pointCloud = new THREE.Points(geometry, material)
    scene.add(pointCloud)

    // 调整相机视角
    const box = new THREE.Box3().setFromObject(pointCloud)
    const center = new THREE.Vector3()
    box.getCenter(center)
    const size = box.getSize(new THREE.Vector3())
    const maxDim = Math.max(size.x, size.y, size.z)

    console.log('Bounding Box Size:', size)
    camera.position.set(center.x, center.y, maxDim * 2)
    camera.lookAt(center)
    controls.target.copy(center)
    controls.update()

    handleResize()
  } catch (err) {
    error.value = true
    errorMessage.value = err instanceof Error ? err.message : '点云加载失败'
    console.error('点云加载错误:', err)
  } finally {
    loading.value = false
  }
}

// 动画循环
const animate = () => {
  requestAnimationFrame(animate)
  controls.update()
  renderer.render(scene, camera)
}

// 窗口适配
const handleResize = () => {
  const container = renderContainer.value
  if (!container || !camera || !renderer) return

  const width = container.clientWidth
  const height = container.clientHeight
  camera.aspect = width / height
  camera.updateProjectionMatrix()
  renderer.setSize(width, height)
}

// 生命周期
onMounted(() => {
  initScene()
  window.addEventListener('resize', handleResize)
  loadPointCloud()
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
})
</script>

<style scoped>
.point-cloud-viewer {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 500px;
}

.render-container {
  width: 100%;
  height: 100%;
}

.loading-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.loading-text {
  font-size: 18px;
  color: #666;
}

.error-message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 16px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 4px;
  color: #f56c6c;
  z-index: 10;
}
</style>
